
import UIKit

// MARK: - 构建方式
extension UIView {
    /// ```
    /// `translatesAutoresizingMaskIntoConstraints` 会默认设置false
    ///  使用方式：
    ///    private let button: UIButton = .build { button in
    ///        button.setTitle("Tap me!", for state: .normal)
    ///        button.backgroundColor = .systemPink
    ///    }
    /// ```
    public static func build<T: UIView>(_ builder: ((T) -> Void)? = nil) -> T {
        let view = T();
        view.translatesAutoresizingMaskIntoConstraints = false;
        builder?(view)
        
        return view
    }
}

extension UIView: XExtensionWarapper {}

public enum XDashLineDirection: Int {
    case vertical = 0
    case horizontal = 1
}
// MARK: - 关于UIView的 圆角、阴影、边框、虚线 的设置
public extension Wrapper  where Base: UIView {
    // MARK: 添加圆角
    /// 添加圆角
    /// - Parameters:
    ///   - conrners: 具体哪个圆角
    ///   - radius: 圆角的大小
    func addCorner(conrners: CACornerMask , radius: CGFloat) {
        self.base.layer.maskedCorners = conrners
        self.base.layer.cornerRadius = abs(CGFloat(Int(radius * 100)) / 100);
        self.base.layer.masksToBounds = true;
    }
    // MARK: 通过遮罩图层，添加圆角
    /// 添加圆角
    /// - Parameters:
    ///   - conrners: 具体哪个圆角
    ///   - radius: 圆角的大小
    func addCorner(conrners: UIRectCorner , radius: CGFloat) {
        let maskPath = UIBezierPath(roundedRect: self.base.bounds, byRoundingCorners: conrners, cornerRadii: CGSize(width: radius, height: abs(CGFloat(Int(radius * 100)) / 100)))
        let maskLayer = CAShapeLayer()
        maskLayer.frame = self.base.bounds
        maskLayer.path = maskPath.cgPath
        self.base.layer.mask = maskLayer
    }
    // MARK: 添加圆角和边框
    /// 添加圆角和边框
    /// - Parameters:
    ///   - conrners: 具体哪个圆角
    ///   - radius: 圆角的大小
    ///   - borderWidth: 边框的宽度
    ///   - borderColor: 边框的颜色
    func addCorner(conrners: UIRectCorner , radius: CGFloat, borderWidth: CGFloat, borderColor: UIColor) {
        let maskPath = UIBezierPath(roundedRect: self.base.bounds, byRoundingCorners: conrners, cornerRadii: CGSize(width: radius, height: abs(CGFloat(Int(radius * 100)) / 100)))
        let maskLayer = CAShapeLayer()
        maskLayer.frame = self.base.bounds
        maskLayer.path = maskPath.cgPath
        self.base.layer.mask = maskLayer
        
        // Add border
        let borderLayer = CAShapeLayer()
        borderLayer.path = maskLayer.path
        borderLayer.fillColor = UIColor.clear.cgColor
        borderLayer.strokeColor = borderColor.cgColor
        borderLayer.lineWidth = borderWidth
        borderLayer.frame =  self.base.bounds
        self.base.layer.addSublayer(borderLayer)
    }
    // MARK: 给继承于view的类添加阴影
    /// 给继承于view的类添加阴影
    /// - Parameters:
    ///   - shadowColor: 阴影的颜色
    ///   - shadowOffset: 阴影的偏移度：CGSizeMake(X[正的右偏移,负的左偏移], Y[正的下偏移,负的上偏移])
    ///   - shadowOpacity: 阴影的透明度
    ///   - shadowRadius: 阴影半径，默认 3
    func addShadow(shadowColor: UIColor, shadowOffset: CGSize, shadowOpacity: Float, shadowRadius: CGFloat = 3) {
        // 设置阴影颜色
        base.layer.shadowColor = shadowColor.cgColor
        // 设置透明度
        base.layer.shadowOpacity = shadowOpacity
        // 设置阴影半径
        base.layer.shadowRadius = shadowRadius
        // 设置阴影偏移量
        base.layer.shadowOffset = shadowOffset
    }
    
    // MARK: 添加阴影和圆角并存
   /// 添加阴影和圆角并存
   ///
   /// - Parameter superview: 父视图
   /// - Parameter conrners: 具体哪个圆角
   /// - Parameter radius: 圆角大小
   /// - Parameter shadowColor: 阴影的颜色
   /// - Parameter shadowOffset: 阴影的偏移度：CGSizeMake(X[正的右偏移,负的左偏移], Y[正的下偏移,负的上偏移])
   /// - Parameter shadowOpacity: 阴影的透明度
   /// - Parameter shadowRadius: 阴影半径，默认 3
   ///
   /// - Note1: 如果在异步布局(如：SnapKit布局)中使用，要在布局后先调用 layoutIfNeeded，再使用该方法
   /// - Note2: 如果在添加阴影的视图被移除，底部插入的父视图的layer是不会被移除的⚠️
   func addCornerAndShadow(superview: UIView, conrners: UIRectCorner , radius: CGFloat = 3, shadowColor: UIColor, shadowOffset: CGSize, shadowOpacity: Float, shadowRadius: CGFloat = 3) {
       
       let maskPath = UIBezierPath(roundedRect: self.base.bounds, byRoundingCorners: conrners, cornerRadii: CGSize(width: radius, height: radius))
       let maskLayer = CAShapeLayer()
       maskLayer.frame = self.base.bounds
       maskLayer.path = maskPath.cgPath
       self.base.layer.mask = maskLayer
       
       let subLayer = CALayer()
       let fixframe = self.base.frame
       subLayer.frame = fixframe
       subLayer.cornerRadius = radius
       subLayer.backgroundColor = shadowColor.cgColor
       subLayer.masksToBounds = false
       // shadowColor阴影颜色
       subLayer.shadowColor = shadowColor.cgColor
       // shadowOffset阴影偏移,x向右偏移3，y向下偏移2，默认(0, -3),这个跟shadowRadius配合使用
       subLayer.shadowOffset = shadowOffset
       // 阴影透明度，默认0
       subLayer.shadowOpacity = shadowOpacity
       // 阴影半径，默认3
       subLayer.shadowRadius = shadowRadius
       subLayer.shadowPath = maskPath.cgPath
       superview.layer.insertSublayer(subLayer, below: self.base.layer)
   }
    
    // MARK: 通过贝塞尔曲线View添加阴影和圆角
    /// 通过贝塞尔曲线View添加阴影和圆角
    ///
    /// - Parameter conrners: 具体哪个圆角(暂时只支持：allCorners)
    /// - Parameter radius: 圆角大小
    /// - Parameter shadowColor: 阴影的颜色
    /// - Parameter shadowOffset: 阴影的偏移度：CGSizeMake(X[正的右偏移,负的左偏移], Y[正的下偏移,负的上偏移])
    /// - Parameter shadowOpacity: 阴影的透明度
    /// - Parameter shadowRadius: 阴影半径，默认 3
    ///
    /// - Note: 提示：如果在异步布局(如：SnapKit布局)中使用，要在布局后先调用 layoutIfNeeded，再使用该方法或者在override func layoutSublayers(of layer: CALayer) {} 里面调用，也要使用 layoutIfNeeded
    func addViewCornerAndShadow(conrners: UIRectCorner , radius: CGFloat = 3, shadowColor: UIColor, shadowOffset: CGSize, shadowOpacity: Float, shadowRadius: CGFloat = 3) {
        // 切圆角
        base.layer.shadowColor = shadowColor.cgColor
        base.layer.shadowOffset = shadowOffset
        base.layer.shadowOpacity = shadowOpacity
        base.layer.shadowRadius = shadowRadius
        base.layer.cornerRadius = radius
       
        // 路径阴影
        let path = UIBezierPath.init(roundedRect: base.bounds, byRoundingCorners: conrners, cornerRadii: CGSize.init(width: radius, height: radius))
        base.layer.shadowPath = path.cgPath
    }
    // MARK: 添加边框
    /// 添加边框
    /// - Parameters:
    ///   - width: 边框宽度
    ///   - color: 边框颜色
    func addBorder(borderWidth: CGFloat, borderColor: UIColor) {
        base.layer.borderWidth = borderWidth
        base.layer.borderColor = borderColor.cgColor
        base.layer.masksToBounds = true
    }
    
    // MARK: 添加顶部的 边框
    /// 添加顶部的 边框
    /// - Parameters:
    ///   - borderWidth: 边框宽度
    ///   - borderColor: 边框颜色
    func addBorderTop(borderWidth: CGFloat, borderColor: UIColor) {
        base.addBorderUtility(x: 0, y: 0, width: base.frame.width, height: borderWidth, color: borderColor)
    }
    
    // MARK: 5.8、添加顶部的 内边框
    /// 添加顶部的 内边框
    /// - Parameters:
    ///   - borderWidth: 边框宽度
    ///   - borderColor: 边框颜色
    ///   - padding: 边框距离边上的距离
    func addBorderTopWithPadding(borderWidth: CGFloat, borderColor: UIColor, padding: CGFloat) {
        base.addBorderUtility(x: padding, y: 0, width: base.frame.width - padding * 2, height: borderWidth, color: borderColor)
    }
    
    // MARK: 添加底部的 边框
    /// 添加底部的 边框
    /// - Parameters:
    ///   - borderWidth: 边框宽度
    ///   - borderColor: 边框颜色
    func addBorderBottom(borderWidth: CGFloat, borderColor: UIColor) {
        base.addBorderUtility(x: 0, y: base.frame.height - borderWidth, width: base.frame.width, height: borderWidth, color: borderColor)
    }
    // MARK: 添加左边的 边框
    /// 添加左边的 边框
    /// - Parameters:
    ///   - borderWidth: 边框宽度
    ///   - borderColor: 边框颜色
    func addBorderLeft(borderWidth: CGFloat, borderColor: UIColor) {
        base.addBorderUtility(x: 0, y: 0, width: borderWidth, height: base.frame.height, color: borderColor)
    }
    
    // MARK: 添加右边的 边框
    /// 添加右边的 边框
    /// - Parameters:
    ///   - borderWidth: 边框宽度
    ///   - borderColor: 边框颜色
    func addBorderRight(borderWidth: CGFloat, borderColor: UIColor) {
        base.addBorderUtility(x: base.frame.width - borderWidth, y: 0, width: borderWidth, height: base.frame.height, color: borderColor)
    }
    
    // MARK: 画圆环
    /// 画圆环
    /// - Parameters:
    ///   - fillColor: 内环的颜色
    ///   - strokeColor: 外环的颜色
    ///   - strokeWidth: 外环的宽度
    func drawCircle(fillColor: UIColor, strokeColor: UIColor, strokeWidth: CGFloat) {
        let ciecleRadius = self.base.bounds.size.width > self.base.bounds.size.height ? self.base.bounds.size.height : self.base.bounds.width
        let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: ciecleRadius, height: ciecleRadius), cornerRadius: ciecleRadius / 2)
        let shapeLayer = CAShapeLayer()
        shapeLayer.path = path.cgPath
        shapeLayer.fillColor = fillColor.cgColor
        shapeLayer.strokeColor = strokeColor.cgColor
        shapeLayer.lineWidth = strokeWidth
        self.base.layer.addSublayer(shapeLayer)
    }
    // MARK: 绘制虚线
    /// 绘制虚线
    /// - Parameters:
    ///   - strokeColor: 虚线颜色
    ///   - lineLength: 每段虚线的长度
    ///   - lineSpacing: 每段虚线的间隔
    ///   - direction: 虚线的方向
    func drawDashLine(strokeColor: UIColor,
                       lineLength: CGFloat = 4,
                      lineSpacing: CGFloat = 4,
                        direction: XDashLineDirection = .horizontal) {
        // 线粗
        let lineWidth = direction == .horizontal ? self.base.bounds.size.height : self.base.bounds.size.width
        
        let shapeLayer = CAShapeLayer()
        shapeLayer.bounds = self.base.bounds
        shapeLayer.anchorPoint = CGPoint(x: 0, y: 0)
        shapeLayer.fillColor = UIColor.blue.cgColor
        shapeLayer.strokeColor = strokeColor.cgColor
        
        shapeLayer.lineWidth = lineWidth
        shapeLayer.lineJoin = CAShapeLayerLineJoin.round
        shapeLayer.lineDashPhase = 0
        // 每一段虚线长度 和 每两段虚线之间的间隔
        shapeLayer.lineDashPattern = [NSNumber(value: lineLength), NSNumber(value: lineSpacing)]
        // 起点
        let path = CGMutablePath()
        if direction == .horizontal {
            path.move(to: CGPoint(x: 0, y: lineWidth / 2))
            // 终点
            // 横向 y = lineWidth / 2
            path.addLine(to: CGPoint(x: self.base.bounds.size.width, y: lineWidth / 2))
        } else {
            path.move(to: CGPoint(x: lineWidth / 2, y: 0))
            // 终点
            // 纵向 Y = view 的height
            path.addLine(to: CGPoint(x: lineWidth / 2, y: self.base.bounds.size.height))
        }
        shapeLayer.path = path
        self.base.layer.addSublayer(shapeLayer)
    }
    
    // MARK: 添加内阴影
    /// 添加内阴影
    /// - Parameters:
    ///   - shadowColor: 阴影的颜色
    ///   - shadowOffset: 阴影的偏移度：CGSizeMake(X[正的右偏移,负的左偏移], Y[正的下偏移,负的上偏移])
    ///   - shadowOpacity: 阴影的透明度
    ///   - shadowRadius: 阴影半径，默认 3
    ///   - insetBySize: 内阴影偏移大小
    func addInnerShadowLayer(shadowColor: UIColor, shadowOffset: CGSize = CGSize(width: 0, height: 0), shadowOpacity: Float = 0.5, shadowRadius: CGFloat = 3, insetBySize: CGSize = CGSize(width: -42, height: -42)) {
        let shadowLayer = CAShapeLayer()
        shadowLayer.frame = self.base.bounds
        shadowLayer.shadowColor = shadowColor.cgColor
        shadowLayer.shadowOffset = shadowOffset
        shadowLayer.shadowOpacity = shadowOpacity
        shadowLayer.shadowRadius = shadowRadius
        shadowLayer.fillRule = .evenOdd
        let path = CGMutablePath()
        path.addRect(self.base.bounds.insetBy(dx: insetBySize.width, dy: insetBySize.height))
      
        // let someInnerPath = UIBezierPath(roundedRect: self.base.bounds, cornerRadius: innerPathRadius).cgPath
        let someInnerPath = UIBezierPath(roundedRect: self.base.bounds, cornerRadius: shadowRadius).cgPath
        path.addPath(someInnerPath)
        path.closeSubpath()
        shadowLayer.path = path
        let maskLayer = CAShapeLayer()
        maskLayer.path = someInnerPath
        shadowLayer.mask = maskLayer
        self.base.layer.addSublayer(shadowLayer)
    }
    
    // MARK: 毛玻璃效果
    /// 毛玻璃效果
    /// - Parameters:
    ///   - alpha: 可设置模糊的程度(0-1)，越大模糊程度越大
    ///   - size: 毛玻璃的size
    ///   - style: 模糊效果
    func effectViewWithAlpha(alpha: CGFloat = 1.0, size: CGSize? = nil, style: UIBlurEffect.Style = .light, isAddVibrancy: Bool = true) {
        // 模糊视图的大小
        var visualEffectViewSize = CGSize(width: 0, height: 0)
        if let weakSize = size {
            visualEffectViewSize = weakSize
        } else {
            visualEffectViewSize = self.base.bounds.size
        }
        // 创建一个模糊效果
        let blurEffect = UIBlurEffect(style: style)
        let visualEffectView = UIVisualEffectView(effect: blurEffect)
        // 毛玻璃的透明度
        visualEffectView.alpha = alpha
        visualEffectView.frame.size = visualEffectViewSize
        // 创建并添加vibrancy视图, 振动模糊，增强前景元素
        if isAddVibrancy {
            /*
             UIVibrancyEffect 主要用于放大和调整UIVisualEffectView 视图下面的内容的颜色，同时让UIVisualEffectView的  contentView中的内容看起来更加生动。通常UIVibrancyEffect 对象是与UIBlurEffect一起使用
             */
            let vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: blurEffect))
            vibrancyView.frame.size = visualEffectViewSize
            visualEffectView.contentView.addSubview(vibrancyView)
        }
        self.base.addSubview(visualEffectView)
    }
}

extension UIView {
    /// 边框的私有内容
    fileprivate func addBorderUtility(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat, color: UIColor) {
        let border = CALayer()
        border.backgroundColor = color.cgColor
        border.frame = CGRect(x: x, y: y, width: width, height: height)
        layer.addSublayer(border)
    }
}

// MARK: - 自定义链式编程
public extension UIView {
    // MARK: 设置 tag 值
    /// 设置 tag 值
    /// - Parameter tag: 值
    /// - Returns: 返回自身
    @discardableResult
    func tag(_ tag: Int) -> Self {
        self.tag = tag
        return self
    }
    
    // MARK: 设置圆角
    /// 设置圆角
    /// - Parameter cornerRadius: 圆角
    /// - Returns: 返回自身
    @discardableResult
    func corner(_ cornerRadius: CGFloat) -> Self {
        layer.cornerRadius = cornerRadius
        layer.masksToBounds = true
        return self
    }
    
    // MARK: 图片的模式
    /// 图片的模式
    /// - Parameter mode: 模式
    /// - Returns: 返回图片的模式
    @discardableResult
    func contentMode(_ mode: UIView.ContentMode) -> Self {
        contentMode = mode
        return self
    }
    // MARK: 设置背景色
    /// 设置背景色
    /// - Parameter color: 颜色
    /// - Returns: 返回自身
    @discardableResult
    func backgroundColor(_ color: UIColor?) -> Self {
        backgroundColor = color
        return self
    }
    
    // MARK: 设置十六进制颜色
    /// 设置十六进制颜色
    /// - Parameter hex: 十六进制颜色
    /// - Returns: 返回自身
    @discardableResult
    func backgroundColor(_ hex: String) -> Self {
        backgroundColor = UIColor(hex: hex)
        return self
    }
    
    // MARK: 设置 frame
    /// 设置 frame
    /// - Parameter frame: frame
    /// - Returns: 返回自身
    @discardableResult
    func frame(_ frame: CGRect) -> Self {
        self.frame = frame
        return self
    }
    // MARK: 被添加到某个视图上
    /// 被添加到某个视图上
    /// - Parameter superView: 父视图
    /// - Returns: 返回自身
    @discardableResult
    func addTo(_ superView: UIView) -> Self {
        superView.addSubview(self)
        return self
    }
    
    // MARK: 设置是否支持触摸
    /// 设置是否支持触摸
    /// - Parameter isUserInteractionEnabled: 是否支持触摸
    /// - Returns: 返回自身
    @discardableResult
    func isUserInteractionEnabled(_ isUserInteractionEnabled: Bool) -> Self {
        self.isUserInteractionEnabled = isUserInteractionEnabled
        return self
    }
    
    // MARK: 设置是否隐藏
    /// 设置是否隐藏
    /// - Parameter isHidden: 是否隐藏
    /// - Returns: 返回自身
    @discardableResult
    func isHidden(_ isHidden: Bool) -> Self {
        self.isHidden = isHidden
        return self
    }
    // MARK: 设置透明度
    /// 设置透明度
    /// - Parameter alpha: 透明度
    /// - Returns: 返回自身
    @discardableResult
    func alpha(_ alpha: CGFloat) -> Self {
        self.alpha = alpha
        return self
    }
    
    // MARK: 设置tintColor
    /// 设置tintColor
    /// - Parameter tintColor: tintColor description
    /// - Returns: 返回自身
    @discardableResult
    func tintColor(_ tintColor: UIColor) -> Self {
        self.tintColor = tintColor
        return self
    }
}
